home *** CD-ROM | disk | FTP | other *** search
- /* chatnode server - based on conversd written by DK5SG
- * ported to WNOS by DB3FL - 9109xx/9110xx
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <ctype.h>
- #include "global.h"
- #include "config.h"
- #ifdef CHATNODE
- #ifdef MAILBOX
- #include "mailbox.h"
- #include "netuser.h"
- #endif
- #include "timer.h"
- #include "cmdparse.h"
- #include "socket.h"
- #include "session.h"
- #include "files.h"
- #include "commands.h"
-
- static char *cxxtime __ARGS((char *line));
- extern char *ptime __ARGS((long *t));
-
- static int free_connection __ARGS((register struct convection *cp));
- static int free_closed_connections __ARGS((int argc,char *argv[],void *p));
- static int update_permlinks __ARGS((char *name,struct convection *cp));
- static struct convection *alloc_connection __ARGS((int fd));
- static int clear_locks __ARGS((int argc,char *argv[],void *p));
- static int send_user_change_msg __ARGS((char *name,char *host,int oldchannel,int newchannel));
- static char *formatline __ARGS((char *prefix,char *text));
- static int send_msg_to_user __ARGS((char *fromname,char *toname,char *text));
- static int send_msg_to_channel __ARGS((char *fromname,int channel,char *text));
- static char *timestring __ARGS((long gmt));
- static int send_invite_msg __ARGS((char *fromname,char *toname,int channel));
- static int bye_command __ARGS((struct convection *cp));
- static int channel_command __ARGS((struct convection *cp));
- static int help_command __ARGS((struct convection *cp));
- static int invite_command __ARGS((struct convection *cp));
- static int links_command __ARGS((struct convection *cp));
- static int msg_command __ARGS((struct convection *cp));
- static int name_command __ARGS((struct convection *cp));
- static int who_command __ARGS((struct convection *cp));
- static int h_cmsg_command __ARGS((struct convection *cp));
- static int h_host_command __ARGS((struct convection *cp));
- static int h_invi_command __ARGS((struct convection *cp));
- static int h_user_command __ARGS((struct convection *cp));
- static int h_umsg_command __ARGS((struct convection *cp));
-
- static void conv_incom __ARGS((int s,void *t,void *p));
- static char *getarg __ARGS((char *line, int all));
-
- int Sconv = -1;
- char *myhostname = NULLCHAR;
-
- char cnumber[] = "%s *** Channel numbers must be in the range 0..%d.\n";
-
- #define MAXCHANNEL 32767
- #define MAX_WAITTIME (60*60*3)
-
- struct convection {
- int type; /* Connection type */
- #define CT_UNKNOWN 0
- #define CT_USER 1
- #define CT_HOST 2
- #define CT_CLOSED 3
- char name[10]; /* Name of user or host */
- char host[10]; /* Name of host where user is logged on */
- struct convection *via; /* Pointer to neighbor host */
- int channel; /* Channel number */
- int32 time; /* Connect time */
- int locked; /* Set if mesg already sent */
- int fd; /* Socket descriptor */
- int fmask; /* Socket mask */
- char ibuf[LINELEN]; /* Input buffer */
- int received; /* Number of bytes received */
- int xmitted; /* Number of bytes transmitted */
- struct convection *next; /* Linked list pointer */
- };
-
- #define CM_UNKNOWN (1 << CT_UNKNOWN)
- #define CM_USER (1 << CT_USER)
- #define CM_HOST (1 << CT_HOST)
- #define CM_CLOSED (1 << CT_CLOSED)
-
- #define NULLCONNECTION ((struct convection *) 0)
-
- static struct convection *convections;
-
- struct permlink {
- char *name; /* Name of host */
- char *link_info; /* Name of socket to connect to */
- char *command; /* Optional connect command */
- struct convection *convection;/* Pointer to associated connection */
- int32 statetime; /* Time of last (dis)connect */
- int tries; /* Number of connect tries */
- int32 waittime; /* Time between connect tries */
- int32 retrytime; /* Time of next connect try */
- int fd; /* socket descriptor */
- struct permlink *next; /* Linked list pointer */
- };
- #define NULLPERMLINK ((struct permlink *) 0)
-
- static struct permlink *permlinks;
-
- /* Stop chatnode server */
- int conv0(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- close_s(Sconv);
- Sconv = -1;
- return 0;
- }
-
- /* Start up chatnode server */
- int conv1(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct sockaddr_in lsocket;
- int s;
-
- if(Sconv != -1){
- return 0;
- }
- psignal(Curproc,0); /* Don't keep the parser waiting */
- chname(Curproc,"Chatnode");
-
- lsocket.sin_family = AF_INET;
- lsocket.sin_addr.s_addr = INADDR_ANY;
- lsocket.sin_port = (argc < 2) ? IPPORT_CHATNODE : atoi(argv[1]);
-
- Sconv = socket(AF_INET,SOCK_STREAM,0);
- bind(Sconv,(char *)&lsocket,sizeof(lsocket));
- listen(Sconv,1);
- myhostname = strdup(Hostname);
- for(;;){
- if((s = accept(Sconv,NULLCHAR,(int *)NULL)) == -1)
- break; /* Service is shutting down */
-
- if(availmem() < Memthresh){
- shutdown(s,1);
- } else {
- /* Spawn a server */
- newproc("chatnode",2048,conv_incom,s,0,NULL);
- }
- }
-
- return 0;
- }
-
- static char *getarg(line, all)
- char *line;
- int all;
- {
- char *arg;
- int c;
- static char *p;
-
- if (line) p = line;
- while (isspace(uchar(*p))) p++;
- if (all) return p;
- arg = p;
- while (*p && !isspace(uchar(*p))) {
- c = tolower(uchar(*p));
- *p++ = c;
- }
- if (*p) *p++ = '\0';
- return arg;
- }
-
- static char *cxxtime(line)
- char *line;
- {
- extern char *Months[];
- static char buf[12];
- char *cp;
- int i, day;
- cp = line;
- while(isspace(*cp)) /* skip initial blanks */
- ++cp;
- if(*cp == '\0')
- return NULLCHAR;
- if(strlen(cp) < 22)
- return NULLCHAR;
- cp += 5;
- day = atoi(cp);
- if(*(++cp) != ' ')
- ++cp;
- ++cp;
- for(i=0; i < 12; ++i)
- if(strnicmp(Months[i],cp,3) == 0)
- break;
- if(i == 12)
- return NULLCHAR;
- sprintf(buf,"%2d-%3s-%2d %02d:%02d",
- day, Months[i], atoi(cp + 4), atoi(cp + 7), atoi(cp + 10));
- return buf;
- }
-
- static int free_connection(cp)
- register struct convection *cp;
- {
- register struct permlink *p;
-
- for (p = permlinks; p; p = p->next)
- if (p->convection == cp) p->convection = NULLCONNECTION;
- if (cp->fmask) close_s(cp->fd);
- free((char *) cp);
- return 0;
- }
-
- static int free_closed_connections(argc,argv,pp)
- int argc;
- char *argv[];
- void *pp;
- {
- register struct convection *cp, *p;
-
- for (p = NULLCONNECTION, cp = convections; cp; )
- if (cp->type == CT_CLOSED ||
- cp->type == CT_UNKNOWN && cp->time + 300 < Clock) {
- if (p) {
- p->next = cp->next;
- free_connection(cp);
- cp = p->next;
- } else {
- convections = cp->next;
- free_connection(cp);
- cp = convections;
- }
- } else {
- p = cp;
- cp = cp->next;
- }
- return 0;
- }
-
- static int update_permlinks(name, cp)
- char *name;
- struct convection *cp;
- {
- register struct permlink *p;
-
- for (p = permlinks; p; p = p->next)
- if (!strcmp(p->name, name)) {
- p->convection = cp;
- p->statetime = Clock;
- p->tries = 0;
- p->waittime = 60;
- p->retrytime = Clock + p->waittime;
- }
- return 0;
- }
-
- static struct convection *alloc_connection(fd)
- int fd;
- {
- register struct convection *cp;
-
- cp = (struct convection *)callocw(1, sizeof(struct convection ));
- cp->fd = cp->fmask = fd;
- cp->time = Clock;
- cp->next = convections;
- convections = cp;
- return cp;
- }
-
- static int clear_locks(argc,argv,pp)
- int argc;
- char *argv[];
- void *pp;
- {
- register struct convection *p;
-
- for (p = convections; p; p = p->next) p->locked = 0;
- return 0;
- }
-
- static int send_user_change_msg(name, host, oldchannel, newchannel)
- char *name, *host;
- int oldchannel, newchannel;
- {
- time_t cxtime;
- register struct convection *p;
-
- time(&cxtime);
- for (p = convections; p; p = p->next) {
- if (p->type == CT_USER && !p->via && !p->locked) {
- if (p->channel == oldchannel) {
- if (newchannel >= 0)
- p->xmitted += usprintf(p->fd, "%s *** %s switched to channel %d.\n", cxxtime(ptime(&cxtime)),name, newchannel);
- else
- p->xmitted += usprintf(p->fd, "%s *** %s signed off.\n", cxxtime(ptime(&cxtime)), name);
- p->locked = 1;
- }
- if (p->channel == newchannel) {
- p->xmitted += usprintf(p->fd, "%s *** %s signed on.\n", cxxtime(ptime(&cxtime)), name);
- p->locked = 1;
- }
- }
- if (p->type == CT_HOST && !p->locked) {
- p->xmitted += usprintf(p->fd,
- "/\377\200USER %s %s %d %d %d\n",
- name, host, 0, oldchannel, newchannel);
- p->locked = 1;
- }
- }
- return 0;
- }
-
- static char *formatline(prefix, text)
- char *prefix, *text;
- {
-
- #define PREFIXLEN 12
- #define CLINELEN 70
-
- register char *f, *t, *x;
- register int l, lw;
-
- static char buf[2048];
-
- for (f = prefix, t = buf; *f; *t++ = *f++) ;
- l = (int)(t - buf);
- f = text;
-
- for (; ; ) {
- while (isspace(uchar(*f))) f++;
- if (!*f) {
- *t++ = '\n';
- *t = '\0';
- return buf;
- }
- for (x = f; *x && !isspace(uchar(*x)); x++) ;
- lw = (int)(x - f);
- if (l > PREFIXLEN && l + 1 + lw > CLINELEN) {
- *t++ = '\n';
- l = 0;
- }
- do {
- *t++ = ' ';
- l++;
- } while (l < PREFIXLEN);
- while (lw--) {
- *t++ = *f++;
- l++;
- }
- }
- return 0;
- }
-
- static int send_msg_to_user(fromname, toname, text)
- char *fromname, *toname, *text;
- {
- register struct convection *p;
- char buffer[20];
-
- for (p = convections; p; p = p->next) {
- if (p->type == CT_USER && !strcmp(p->name, toname))
- if (p->via) {
- if (!p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200UMSG %s %s %s", fromname, toname, text);
- p->via->locked = 1;
- }
- } else {
- if (!p->locked) {
- if (strcmp(fromname, "chatnode")) {
- sprintf(buffer, "<*%s*>:", fromname);
- p->xmitted += usprintf(p->fd,"%s ",
- formatline(buffer, text));
- } else {
- p->xmitted += usprintf(p->fd,"%s\n", text);
- }
- p->locked = 1;
- }
- }
- }
- return 0;
- }
-
- static int send_msg_to_channel(fromname, channel, text)
- char *fromname;
- int channel;
- char *text;
- {
- register struct convection *p;
- char buffer[20];
-
- for (p = convections; p; p = p->next) {
- if (p->type == CT_USER && p->channel == channel)
- if (p->via) {
- if (!p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200CMSG %s %d %s\n", fromname, channel, text);
- p->via->locked = 1;
- }
- } else {
- if (!p->locked) {
- sprintf(buffer, "<%s>:", fromname);
- p->xmitted += usprintf(p->fd,"%s",
- formatline(buffer, text));
- p->locked = 1;
- }
- }
- }
- return 0;
- }
-
- static int send_invite_msg(fromname, toname, channel)
- char *fromname, *toname;
- int channel;
- {
- time_t cxtime;
- char invitetext[] = "\n\007\007%s *** From %s - Please join CHATNODE channel %d.\n\007\007\n";
- char responsetext[] = "%s *** Invitation sent to %s";
- char cnvd[] = "chatnode";
-
- char buffer[LINELEN];
- struct convection *p;
- #ifdef MAILBOX
- int i;
- struct mbx *m;
- #endif
-
- time(&cxtime);
- for (p = convections; p; p = p->next) {
- #ifdef MAILBOX
- for (i = 0; i < NUMMBX; i++){
- if((m = Mbox[i]) != NULLMBX){
- if(m->state == MBX_CMD && !strcmp(m->name,toname)) {
- p->xmitted += usprintf(m->user, invitetext, cxxtime(ptime(&cxtime)), fromname, channel);
- usflush(m->user);
- clear_locks(NULL,NULLCHAR,NULL);
- sprintf(buffer, responsetext, cxxtime(ptime(&cxtime)),toname);
- send_msg_to_user(cnvd, fromname, buffer);
- return 0;
- }
- }
- }
- #endif
- if (p->type == CT_USER && !strcmp(p->name, toname)) {
- if (p->channel == channel) {
- clear_locks(NULL,NULLCHAR,NULL);
- sprintf(buffer, "%s *** User %s is already on this channel.", cxxtime(ptime(&cxtime)),toname);
- send_msg_to_user(cnvd, fromname, buffer);
- return 0;
- }
- if (!p->via && !p->locked) {
- time(&cxtime);
- p->xmitted += usprintf(p->fd, invitetext, cxxtime(ptime(&cxtime)), fromname, channel);
- clear_locks(NULL,NULLCHAR,NULL);
- sprintf(buffer, responsetext, cxxtime(ptime(&cxtime)), toname);
- send_msg_to_user(cnvd, fromname, buffer);
- return 0;
- }
- if (p->via && !p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200INVI %s %s %d\n", fromname, toname, channel);
- return 0;
- }
- }
- }
- for (p = convections; p; p = p->next) {
- if (p->type == CT_HOST && !p->locked) {
- p->xmitted += usprintf(p->fd,
- "/\377\200INVI %s %s %d\n", fromname, toname, channel);
- }
- }
- return 0;
- }
-
- static int bye_command(cp)
- struct convection *cp;
- {
- register struct convection *p;
-
- switch (cp->type) {
- case CT_UNKNOWN:
- cp->type = CT_CLOSED;
- break;
- case CT_USER:
- cp->type = CT_CLOSED;
- clear_locks(NULL,NULLCHAR,NULL);
- send_user_change_msg(cp->name, cp->host, cp->channel, -1);
- break;
- case CT_HOST:
- cp->type = CT_CLOSED;
- update_permlinks(cp->name, NULLCONNECTION);
- for (p = convections; p; p = p->next)
- if (p->via == cp) {
- p->type = CT_CLOSED;
- clear_locks(NULL,NULLCHAR,NULL);
- send_user_change_msg(p->name, p->host, p->channel, -1);
- }
- break;
- case CT_CLOSED:
- break;
- }
- return 0;
- }
-
- static int channel_command(cp)
- struct convection *cp;
- {
- time_t cxtime;
- char s[7];
- int newchannel;
-
- time(&cxtime);
- s[0] = '\0';
- sscanf(cp->ibuf,"%*s %6s",s);
- if (s[0] == '\0') {
- cp->xmitted += usprintf(cp->fd,"%s *** You are on channel %d.\n", cxxtime(ptime(&cxtime)),cp->channel);
- return 0;
- }
- newchannel = atoi(s);
- if (newchannel < 0 || newchannel > MAXCHANNEL) {
- cp->xmitted += usprintf(cp->fd,cnumber, cxxtime(ptime(&cxtime)),MAXCHANNEL);
- return 0;
- }
- if (newchannel == cp->channel) {
- cp->xmitted += usprintf(cp->fd,
- "%s *** Already on channel %d.\n", cxxtime(ptime(&cxtime)), cp->channel);
- return 0;
- }
- send_user_change_msg(cp->name, cp->host, cp->channel, newchannel);
- cp->channel = newchannel;
- cp->xmitted += usprintf(cp->fd, "%s *** Now on channel %d.\n", cxxtime(ptime(&cxtime)), cp->channel);
- return 0;
- }
-
- static int help_command(cp)
- struct convection *cp;
- {
- cp->xmitted += usprintf(cp->fd, "Commands may be abbreviated. Commands are:\n");
- cp->xmitted += usprintf(cp->fd, "/? Print help information\n");
- cp->xmitted += usprintf(cp->fd, "/bye Terminate the chatnode session\n");
- cp->xmitted += usprintf(cp->fd, "/channel <n> Switch to channel <n>\n");
- cp->xmitted += usprintf(cp->fd, "/exit Terminate the chatnode session\n");
- cp->xmitted += usprintf(cp->fd, "/help Print help information\n");
- cp->xmitted += usprintf(cp->fd, "/invite <user> Invite <user> to join your channel\n");
- cp->xmitted += usprintf(cp->fd, "/msg <user> <text...> Send a private message to <user>\n");
- cp->xmitted += usprintf(cp->fd, "/quit Terminate the chatnode session\n");
- cp->xmitted += usprintf(cp->fd, "/who [quick] [long] List all users and their channel numbers\n");
- cp->xmitted += usprintf(cp->fd, "/write <user> <text...> Send a private message to <user>\n***\n");
- return 0;
- }
-
- static int invite_command(cp)
- struct convection *cp;
- {
- char toname[10];
-
- toname[0] = '\0';
- sscanf(cp->ibuf,"%*s %8s",toname);
- if (toname[0] != '\0')
- send_invite_msg(cp->name, toname, cp->channel);
- return 0;
- }
-
- static int msg_command(cp)
- struct convection *cp;
- {
- time_t cxtime;
- char dummy[LINELEN], toname[10], *text;
- register struct convection *p;
-
- time(&cxtime);
- toname[0] = '\0';
- sscanf(cp->ibuf,"%s %8s",dummy,toname);
- text = &cp->ibuf[0];
- text += strlen(dummy) + strlen(toname) + 2;
-
- if (!*text) return 0;
- for (p = convections; p; p = p->next)
- if (p->type == CT_USER && !strcmp(p->name, toname))
- break;
- if (!p)
- cp->xmitted += usprintf(cp->fd, "%s *** No such user: %s.\n", cxxtime(ptime(&cxtime)), toname);
- else
- send_msg_to_user(cp->name, toname, text);
- return 0;
- }
-
- static int name_command(cp)
- struct convection *cp;
- {
- time_t cxtime;
- int newchannel;
- char dummy[7];
-
- time(&cxtime);
- cp->name[0] = '\0';
- dummy[0] = '\0';
- sscanf(cp->ibuf,"%*s %8s %6s",cp->name,dummy);
- newchannel = atoi(dummy);
- if (cp->name[0] == '\0') return 0;
- strlwr(cp->name);
- strncpy(cp->host,myhostname,9);
- cp->type = CT_USER;
- cp->xmitted += usprintf(cp->fd,
- "%s *** Host: %s %s\nType /help for Help.\n",
- cxxtime(ptime(&cxtime)), myhostname, Aversion);
- if (newchannel < 0 || newchannel > MAXCHANNEL) {
- cp->xmitted += usprintf(cp->fd,cnumber, cxxtime(ptime(&cxtime)),MAXCHANNEL);
- } else
- cp->channel = newchannel;
- send_user_change_msg(cp->name, cp->host, -1, cp->channel);
- return 0;
- }
-
- static int who_command(cp)
- struct convection *cp;
- {
- char buffer[LINELEN];
- int channel, full = 0, quick = 0;
- struct convection *p;
- #ifdef MAILBOX
- int i;
- struct mbx *m;
- #endif
-
- buffer[0] = '\0';
- sscanf(cp->ibuf,"%*s %2s",buffer);
- switch(tolower(buffer[0])) {
- case 'l':
- full = 1;
- break;
- case 'q':
- quick = 1;
- break;
- }
-
- if (quick) {
- cp->xmitted += usprintf(cp->fd, "Channel Users\n");
- clear_locks(NULL,NULLCHAR,NULL);
- do {
- channel = -1;
- for (p = convections; p; p = p->next) {
- if (p->type == CT_USER && !p->locked && (channel < 0 || channel == p->channel)) {
- if (channel < 0) {
- channel = p->channel;
- sprintf(buffer, "%7d", channel);
- }
- strcat(buffer, " ");
- strcat(buffer, p->name);
- p->locked = 1;
- }
- }
- if (channel >= 0) {
- cp->xmitted += usprintf(cp->fd, "%s\n",buffer);
- }
- } while (channel >= 0);
- } else {
- cp->xmitted += usprintf(cp->fd,
- "User Host Via Channel Duration %s\n",
- full ? " HQueue Receivd Xmitted" : "");
- for (p = convections; p; p = p->next) {
- if (p->type == CT_USER) {
- cp->xmitted += usprintf(cp->fd,
- full ?
- "%-8.8s %-8.8s %-8.8s %7d %12s %5d %7d %7d\n" :
- "%-8.8s %-8.8s %-8.8s %7d %12s\n",
- p->name,
- p->host,
- p->via ? p->via->name : "",
- p->channel,
- tformat(Clock - p->time),
- 0, /* always 0 cuz NOS handles the tx-queue */
- p->received,
- p->xmitted);
- }
- }
- }
- #ifdef MAILBOX
- for (i = 0; i < NUMMBX; i++) {
- if((m = Mbox[i]) != NULLMBX) {
- if(m->state == MBX_CMD) {
- if(quick)
- cp->xmitted += usprintf(cp->fd," LocBBS %s\n",m->name);
- else
- cp->xmitted += usprintf(cp->fd,"%-8s LocBBS@%s\n",m->name,Hostname);
- }
- }
- }
- #endif
- cp->xmitted += usprintf(cp->fd, "***\n");
- return 0;
- }
-
- static int h_cmsg_command(cp)
- struct convection *cp;
- {
- char name[LINELEN], dummy[40], *text;
- int channel;
-
- sscanf(cp->ibuf,"%s %s %d",dummy,name,&channel);
- text = &cp->ibuf[0];
- text += strlen(dummy) + strlen(name) + 2;
- while(isspace(*text) == NULL)
- text++;
- text++;
- if(isprint(*text) != 0)
- send_msg_to_channel(name, channel, text);
- return 0;
- }
-
- static int h_host_command(cp)
- struct convection *cp;
- {
- char name[10];
- register struct convection *p;
- register struct permlink *pp;
-
- name[0] = '\0';
- sscanf(cp->ibuf,"%*s %8s",name);
- if (name[0] == '\0') return 0;
- for (p = convections; p; p = p->next)
- if (!strcmp(p->name, name)) bye_command(p);
- for (pp = permlinks; pp; pp = pp->next)
- if (!strcmp(pp->name, name) && pp->convection && pp->convection != cp)
- bye_command((strcmp(myhostname, name) < 0) ? pp->convection : cp);
- if (cp->type != CT_UNKNOWN) return 0;
- cp->type = CT_HOST;
- strcpy(cp->name,name); /* already allocated */
- update_permlinks(name, cp);
- cp->xmitted += usprintf(cp->fd, "/\377\200HOST %s\n", myhostname);
- for (p = convections; p; p = p->next)
- if (p->type == CT_USER) {
- cp->xmitted += usprintf(cp->fd,
- "/\377\200USER %s %s %d %d %d\n", p->name, p->host, 0, -1, p->channel);
- }
- return 0;
- }
-
- static int h_invi_command(cp)
- struct convection *cp;
- {
- char fromname[10], toname[10];
- int channel;
-
- sscanf(cp->ibuf,"%*s %8s %8s %d",fromname,toname,&channel);
- send_invite_msg(fromname, toname, channel);
- return 0;
- }
-
- static int h_umsg_command(cp)
- struct convection *cp;
- {
- char dummy[LINELEN], fromname[10], toname[10], *text;
-
- sscanf(cp->ibuf,"%s %8s %8s",dummy,fromname,toname);
- text = &cp->ibuf[0];
- text += strlen(dummy) + strlen(fromname) + strlen(toname) + 3;
- if (*text)
- send_msg_to_user(fromname, toname, text);
- return 0;
- }
-
- static int h_user_command(cp)
- struct convection *cp;
- {
- char host[10], name[10];
- int newchannel, oldchannel;
- register struct convection *p;
-
- sscanf(cp->ibuf,"%*s %8s %8s %*s %d %d",name,host,&oldchannel,&newchannel);
-
- for (p = convections; p; p = p->next)
- if (p->type == CT_USER &&
- p->channel == oldchannel &&
- p->via == cp &&
- !strcmp(p->name, name) &&
- !strcmp(p->host, host)) break;
- if (!p) {
- p = (struct convection *)callocw(1, sizeof(struct convection ));
- p->type = CT_USER;
- strncpy(p->name,name,9);
- strncpy(p->host,host,9);
- p->via = cp;
- p->channel = oldchannel;
- p->time = Clock;
- p->next = convections;
- convections = p;
- }
- if ((p->channel = newchannel) < 0) p->type = CT_CLOSED;
- send_user_change_msg(name, host, oldchannel, newchannel);
- return 0;
- }
-
- /* Incoming chatnode session */
- static void conv_incom(s,t,p)
- int s;
- void *t;
- void *p;
- {
- time_t cxtime;
- char arg[LINELEN];
- int arglen, size;
- struct convection *cp;
- struct permlink *pl;
- char *ccp, *cccp;
-
- #ifdef MAILBOX
- int len;
- char fsocket[MAXSOCKSIZE];
- #endif
-
- struct cmdtable {
- char *name;
- int (*fnc) __ARGS((struct convection *cp));
- int states;
- } cmdtable[] = {
- "?", help_command, CM_USER,
- "bye", bye_command, CM_USER,
- "channel", channel_command, CM_USER,
- "exit", bye_command, CM_USER,
- "help", help_command, CM_USER,
- "invite", invite_command, CM_USER,
- "msg", msg_command, CM_USER,
- "name", name_command, CM_UNKNOWN,
- "quit", bye_command, CM_USER,
- "who", who_command, CM_USER,
- "write", msg_command, CM_USER,
-
- "\377\200cmsg", h_cmsg_command, CM_HOST,
- "\377\200host", h_host_command, CM_UNKNOWN,
- "\377\200invi", h_invi_command, CM_HOST,
- "\377\200umsg", h_umsg_command, CM_HOST,
- "\377\200user", h_user_command, CM_HOST,
-
- 0, 0, 0,
- };
- struct cmdtable *cmdp;
-
- sockowner(s,Curproc); /* We own it now */
-
- cp = alloc_connection(s);
-
- for(pl = permlinks; pl; pl = pl->next)
- if(pl->fd == s) {
- pl->convection = cp;
- if (pl->command != NULLCHAR) usprintf(s, "%s",pl->command);
- cp->xmitted += usprintf(s, "/\377\200HOST %s\n", myhostname);
- }
-
- if(pl == NULLPERMLINK) {
- #ifdef MAILBOX
- getpeername(s,fsocket,&len);
- ccp = strdup(psocket(fsocket));
- if((cccp = strchr(ccp,':')) != NULLCHAR)
- *cccp = '\0';
- if(strcmp(ccp,inet_ntoa(Ip_addr)) != 0)
- #endif
- usprintf(cp->fd,"\npse login with '/n <call>'\n\n");
- }
-
- for (; ; ) {
- loop:
- if(cp->type == CT_CLOSED)
- break;
- memset(cp->ibuf,0,sizeof(cp->ibuf));
- if((size = recvline(cp->fd,cp->ibuf,sizeof(cp->ibuf))) <= 0)
- break;
- cp->received += size;
- clear_locks(NULL,NULLCHAR,NULL);
- cp->locked = 1;
- if (*cp->ibuf == '/') {
- ccp = &cp->ibuf[1];
- arg[0] = '\0';
- sscanf(ccp,"%s",arg);
- arglen = strlen(arg);
- for (cmdp = cmdtable; cmdp->name; cmdp++) {
- if (!strncmp(cmdp->name, arg, arglen)) {
- if (cmdp->states & (1 << cp->type))
- (*cmdp->fnc)(cp);
- goto loop;
- }
- }
- if (cp->type == CT_USER) {
- time(&cxtime);
- cp->xmitted += usprintf(cp->fd,
- "%s *** Unknown command '/%s'. Type /help for Help.\n", cxxtime(ptime(&cxtime)), arg);
- }
- goto loop;
- }
- if((ccp = strpbrk(cp->ibuf,"\r\n")) != NULLCHAR)
- *ccp = '\0';
- if(isprint(cp->ibuf[0]) != 0 && cp->type == CT_USER)
- send_msg_to_channel(cp->name, cp->channel, cp->ibuf);
- }
- bye_command(cp);
- free_closed_connections(NULL,NULLCHAR,NULL);
- return;
- }
-
-
- #endif /* CHATNODE */
-